﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using My.Application.Contracts.Comments.Dtos;
using My.Application.Contracts.Issues;
using My.Application.Contracts.Issues.Dtos;
using My.Application.Contracts.Issues.Events;
using My.Domain.Issues;
using My.Domain.Users;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Uow;

namespace My.Application.Issues
{
    public class IssueService : ApplicationService, IIssueService
    {
        private readonly IIssueRepository _issueRepository;
        private readonly IssueManager _issueManager;
        private readonly Volo.Abp.Identity.IIdentityUserAppService _identityUserService;
        private readonly ILocalEventBus _localEventBus;

        public IssueService(IIssueRepository issueRepository,
            IssueManager issueManager,
            Volo.Abp.Identity.IIdentityUserAppService identityUserService,
            ILocalEventBus localEventBus)
        {
            _issueRepository = issueRepository;
            _issueManager = issueManager;
            _identityUserService = identityUserService;
            _localEventBus = localEventBus;
        }

        [Authorize]
        public virtual async Task CreateCommentAsync(CreateCommentDto input)
        {
            //获取问题
            var issueQueryable = await _issueRepository.WithDetailsAsync(x => x.Comments, x => x.IssueLabels);
            var issue = await AsyncExecuter.FirstOrDefaultAsync(issueQueryable.AsTracking(), x => x.Id == input.IssueId);
            if (issue == null)
            {
                throw new UserFriendlyException("问题已经不存在，无法评论");
            }
            //问题添加评论
            issue.AddComment(GuidGenerator.Create(), CurrentUser.Id!.Value, input.Text);
            //更新
            await _issueRepository.UpdateAsync(issue);
        }

        [Authorize]
        public virtual async Task CreateIssueAsync(CreateIssueDto input)
        {
            await _issueRepository.InsertAsync(new Issue(
                id: GuidGenerator.Create(),
                repositoryId: input.RepositoryId,
                title: input.Title,
                text: input.Text
                ));
        }

        [Authorize]
        public virtual async Task<object> GetAllAsync()
        {
            var issueQueryable = await _issueRepository.GetQueryableAsync();
            var issues = await AsyncExecuter.ToListAsync(issueQueryable);
            var list = ObjectMapper.Map<List<Issue>, List<IssueDto>>(issues);
            return new
            {
                Current = 1,
                PageSize = 20,
                Data = list,
                Success = true,
                Total = 100
            };
        }

        /// <summary>
        /// 问题绑定用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [Authorize]
        public virtual async Task AssignAsync(IssueAssignDto input)
        {
            var issue = await _issueRepository.GetAsync(input.IssueId);
            var identityUser = await _identityUserService.GetAsync(input.UserId);
            await _issueManager.AssignToAsync(issue, input.UserId);
            await _issueRepository.UpdateAsync(issue);
            await _localEventBus.PublishAsync(new IssueAssignEvent() { IssueId = input.IssueId, UserId = input.UserId });
        }

        [Authorize]
        public virtual async Task CloseAsync(IssueCloseDto input)
        {
            var issue = await _issueRepository.GetAsync(input.IssueId);
            issue.Close(EnumCloseReason.Normal);
        }

        [Authorize]
        public virtual async Task ReOpenAsync(IssueCloseDto input)
        {
            var issue = await _issueRepository.GetAsync(input.IssueId);
            issue.ReOpen();
        }

        /// <summary>
        /// 获取非活动问题
        /// </summary>
        /// <returns></returns>
        public virtual async Task<List<IssueDto>> GetInActiveIssuesAsync()
        {
            var issues = await _issueRepository.GetIssuesAsync(new InActiveIssueSpecification());
            return ObjectMapper.Map<List<Issue>, List<IssueDto>>(issues);
        }

        /// <summary>
        /// 获取已绑定用户的问题
        /// </summary>
        /// <returns></returns>
        public virtual async Task<List<IssueDto>> GetAssignedIssuesAsync()
        {
            var issues = await _issueRepository.GetIssuesAsync(new AssignedSepcification());
            return ObjectMapper.Map<List<Issue>, List<IssueDto>>(issues);
        }

        /// <summary>
        /// 获取已锁定的问题
        /// </summary>
        /// <returns></returns>
        public virtual async Task<List<IssueDto>> GetLockedIssuesAsync()
        {
            var issues = await _issueRepository.GetIssuesAsync(new LockedSpecification());
            return ObjectMapper.Map<List<Issue>, List<IssueDto>>(issues);
        }
    }
}
